package com.rescue.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.rescue.constant.MessageConstant;
import com.rescue.constant.SysSettingConstant;
import com.rescue.context.BaseContext;
import com.rescue.exception.BaseException;
import com.rescue.forum.dto.*;
import com.rescue.forum.entity.*;
import com.rescue.forum.entity.myentity.ForumFile;
import com.rescue.forum.syssetting.AuditSet;
import com.rescue.forum.syssetting.PostSet;
import com.rescue.forum.vo.AdminGetAttachmentVO;
import com.rescue.forum.vo.ArticleDetailVO;
import com.rescue.forum.vo.ArticlePageVO;
import com.rescue.forum.vo.DownloadFileVO;
import com.rescue.mapper.*;
import com.rescue.result.PageResult;
import com.rescue.service.ArticleService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.function.Consumer;

@Service
public class ArticleServiceImpl implements ArticleService {
    @Autowired
    private ArticleMapper articleMapper;
    @Autowired
    private CommentMapper commentMapper;
    @Autowired
    private AttachmentMapper attachmentMapper;
    @Autowired
    private UserInfoMapper userInfoMapper;
    @Autowired
    private SysSettingMapper sysSettingMapper;
    @Autowired
    private UserIntegralRecordMapper userIntegralRecordMapper;
    @Autowired
    private LikeRecordMapper likeRecordMapper;
    @Autowired
    private UserMessageMapper userMessageMapper;
    @Autowired
    private ArticleAttachmentDownloadMapper articleAttachmentDownloadMapper;

    /**
     * 条件查询文章列表
     *
     * @param articlePageQueryDTO
     * @return
     */
    public PageResult page(ArticlePageQueryDTO articlePageQueryDTO) {
        PageHelper.startPage(articlePageQueryDTO.getPage(), articlePageQueryDTO.getPageSize());
        Page<ArticlePageVO> page = articleMapper.page(articlePageQueryDTO);
        return new PageResult(page.getTotal(), page.getResult());
    }


    /**
     * 根据id删除文章
     *
     * @param articleId
     */
    @Transactional
    public void deleteById(String articleId) {
        //删除板块下所有评论
        commentMapper.deleteByArticleId(articleId);
        //删除板块下所有附件
        attachmentMapper.deleteByArticleId(articleId);
        //删除文章
        articleMapper.deleteByArticleId(articleId);
    }

    /**
     * 修改文章板块
     *
     * @param updateBoardDTO
     */
    public void updateBoard(UpdateBoardDTO updateBoardDTO) {
        //查询板块名称
        ForumArticle forumArticle = new ForumArticle();
        BeanUtils.copyProperties(updateBoardDTO, forumArticle);
        articleMapper.update(forumArticle);
    }

    /**
     * 根据文章Id查询附件
     *
     * @param articleId
     * @return
     */
    public List<AdminGetAttachmentVO> getAttachment(String articleId) {
        return articleMapper.getFileByArticleId(articleId);
    }

    /**
     * 置顶文章
     *
     * @param articleId
     * @param topType
     */
    public void topArticle(String articleId, Integer topType) {
        articleMapper.topArticle(articleId, topType);
    }

    /**
     * 审核文章
     *
     * @param articleId
     */
    public void auditArticle(String articleId) {
        articleMapper.auditArticle(articleId);
    }

    /**
     * 获取用户发布的文章
     *
     * @param userId
     * @return
     */
    public PageResult getUserIssue(Integer userId) {
        Page<ArticlePageVO> page = articleMapper.getByUserId(userId);
        return new PageResult(page.size(), page.getResult());
    }


    /**
     * 获取用户评论的文章
     *
     * @param userId
     * @return
     */
    public PageResult getUserComment(Integer userId) {
        Page<ArticlePageVO> page = articleMapper.getByUserComment(userId);
        return new PageResult(page.size(), page.getResult());
    }


    /**
     * 获取用户点赞的文章
     *
     * @param userId
     * @return
     */
    public PageResult getUserLike(Integer userId) {
        Page<ArticlePageVO> page = articleMapper.getByLike(userId);
        return new PageResult(page.size(), page.getResult());
    }

    /**
     * 发布文章
     *
     * @param publishArticleDTO
     */
    @Transactional
    public void save(PublishArticleDTO publishArticleDTO) {
        Integer userId = BaseContext.getCurrentId();
        UserInfo user = userInfoMapper.getByUserId(userId);
        ForumArticle article = new ForumArticle();
        BeanUtils.copyProperties(publishArticleDTO, article);
        article.setArticleId(String.valueOf(UUID.randomUUID()));
        article.setUserId(userId);
        article.setNickName(user.getNickName());
        article.setUserIpAddress(user.getLastLoginIpAddress());
        article.setPostTime(LocalDateTime.now());
        article.setLastUpdateTime(LocalDateTime.now());
        article.setAttachmentType((publishArticleDTO.getAttachments().size() == 0) ? 0 : 1);
        //查看文章是否需审核
        AuditSet auditSet = JSON.parseObject(sysSettingMapper.getByCode(SysSettingConstant.AUDIT_SETTING), AuditSet.class);
        article.setStatus(auditSet.getPostAudit() ? 1 : 0);
        //添加文章
        articleMapper.save(article);
        //批量添加附加
        List<ForumArticleAttachment> list = new ArrayList<>();
        publishArticleDTO.getAttachments().forEach(new Consumer<ForumFile>() {
            @Override
            public void accept(ForumFile forumFile) {
                ForumArticleAttachment attachment = ForumArticleAttachment.builder().articleId(article.getArticleId())
                        .fileId(String.valueOf(UUID.randomUUID()))
                        .userId(userId).build();
                BeanUtils.copyProperties(forumFile, attachment);
                list.add(attachment);
            }
        });
        if (list.size() != 0) {
            attachmentMapper.insertBatch(list);
        }

        //添加积分记录，修改积分
        //查看发送文章所需积分
        PostSet postSet = JSON.parseObject(sysSettingMapper.getByCode(SysSettingConstant.POST_SETTING), PostSet.class);
        UserIntegralRecord record = UserIntegralRecord.builder()
                .createTime(LocalDateTime.now())
                .userId(BaseContext.getCurrentId())
                .operType(UserIntegralRecord.ARTICLE)
                .operTypeName(UserIntegralRecord.TYPE_ARTICLE)
                .integral(postSet.getPostIntegral())
                .build();
        userIntegralRecordMapper.insert(record);
        //修改积分
        userInfoMapper.update(UserInfo.builder()
                .userId(BaseContext.getCurrentId())
                .currentIntegral(-postSet.getPostIntegral())
                .build());
    }

    /**
     * 用户端查询文章列表
     *
     * @param queryArticleDTO
     * @return
     */
    public PageResult list(QueryArticleDTO queryArticleDTO) {
        PageHelper.startPage(queryArticleDTO.getPage(), queryArticleDTO.getPageSize());
        Page<ArticlePageVO> page = articleMapper.list(queryArticleDTO);
        return new PageResult(page.getTotal(), page.getResult());
    }

    /**
     * 根据id查询文章
     *
     * @param articleId
     * @return
     */
    public ArticleDetailVO getDetail(String articleId) {
        List<ForumArticleAttachment> files = articleMapper.userGetByArticleId(articleId);
        //files.forEach(forumArticleAttachment -> forumArticleAttachment.setFilePath(null));
        ForumArticle article = articleMapper.getById(articleId);
        List<LikeRecord> list = likeRecordMapper.getByArticleIdAndUserId(articleId, BaseContext.getCurrentId());
        //增加文章阅读数
        articleMapper.update(ForumArticle.builder().articleId(articleId).readCount(1).build());

        return ArticleDetailVO.builder()
                .article(article)
                .attachmentList(files)
                .haveLike(list != null && list.size() > 0).build();
    }

    /**
     * 根据关键字查询
     *
     * @param searchDTO
     * @return
     */
    public PageResult search(SearchDTO searchDTO) {
        PageHelper.startPage(searchDTO.getPage(), searchDTO.getPageSize());
        Page<ArticlePageVO> page = articleMapper.search(searchDTO);
        return new PageResult(page.getTotal(), page.getResult());
    }

    /**
     * 点赞
     *
     * @param articleId
     * @param type
     */
    @Transactional
    public void doLike(String articleId, Integer type) {
        Integer userId = BaseContext.getCurrentId();
        UserInfo nowUser = userInfoMapper.getByUserId(userId);
        ForumArticle article = articleMapper.getById(articleId);
        List<LikeRecord> likeRecords = likeRecordMapper.getByArticleIdAndUserId(articleId, userId);
        if (type == 1) {
            if (likeRecords.size() == 0) {
                //新增点赞记录
                LikeRecord likeRecord = LikeRecord.builder().articleId(articleId).createTime(LocalDateTime.now())
                        .userId(userId).authorUserId(article.getUserId())
                        .opType(LikeRecord.ARTICLE).build();
                likeRecordMapper.save(likeRecord);
                //修改文章点赞数
                articleMapper.update(ForumArticle.builder().articleId(articleId).goodCount(1).build());
                //添加消息
                userMessageMapper.save(UserMessage.builder()
                        .receivedUserId(article.getUserId())
                        .articleId(articleId)
                        .messageContent(nowUser.getNickName() + "赞了您")
                        .articleTitle(article.getTitle())
                        .sendUserId(userId)
                        .sendNickName(nowUser.getNickName())
                        .messageType(UserMessage.TYPE_ARTICLE_LIKE)
                        .status(1).createTime(LocalDateTime.now())
                        .build());
            }
        } else if (type == 0) {
            if (likeRecords.size() != 0) {
                //删除点赞记录
                likeRecordMapper.delete(likeRecords);
                //修改文章点赞数
                articleMapper.update(ForumArticle.builder().articleId(articleId).goodCount(-1).build());
            }
        }

    }

    /**
     * 文件下载
     *
     * @param fileId
     * @return
     */
    public DownloadFileVO download(String fileId) {
        ForumArticleAttachment file = attachmentMapper.getById(fileId);
        ForumArticleAttachment attachment = attachmentMapper.getById(fileId);
        ForumArticle article = articleMapper.getById(attachment.getArticleId());
        Integer userId = BaseContext.getCurrentId();

        //下载人
        UserInfo user = userInfoMapper.getByUserId(userId);
        if (file == null) {
            throw new BaseException(MessageConstant.FILE_CANNOT_FIND);
        }
        //查看用户是否下载过
        ForumArticleAttachmentDownload record = attachmentMapper.getDownloadByUserIdAndFileId(fileId, userId);
        if (record != null) {
            //下载过
            articleAttachmentDownloadMapper.update(ForumArticleAttachmentDownload
                    .builder()
                    .fileId(fileId)
                    .userId(userId)
                    .downloadCount(1).build());

        } else {
            if (user.getCurrentIntegral() < file.getIntegral()) {
                throw new BaseException(MessageConstant.INSUFFICIENT_INTEGRATION);
            }
            //首次下载
            articleAttachmentDownloadMapper.save(ForumArticleAttachmentDownload.builder()
                    .userId(userId)
                    .fileId(fileId)
                    .articleId(attachment.getArticleId())
                    .downloadCount(1));
            //发送消息
            userMessageMapper.save(UserMessage
                    .builder()
                    .receivedUserId(article.getUserId())
                    .articleId(attachment.getArticleId())
                    .articleTitle(article.getTitle())
                    .sendUserId(attachment.getUserId())
                    .sendNickName(article.getNickName())
                    .messageType(UserMessage.TYPE_DOWNLOAD_ATTACHMENTS)
                    .messageContent(user.getNickName() + "下载了" + article.getTitle() + "中的文件:" + file.getFileName())
                    .createTime(LocalDateTime.now()).build());
            //新增积分记录
            userIntegralRecordMapper.insert(UserIntegralRecord.builder()
                    .userId(userId)
                    .operType(UserIntegralRecord.DOWNLOAD)
                    .integral(file.getIntegral())
                    .createTime(LocalDateTime.now())
                    .operTypeName(UserIntegralRecord.TYPE_DOWNLOAD)
                    .build());
            //修改用户积分
            userInfoMapper.update(UserInfo.builder()
                    .userId(userId)
                    .currentIntegral(-file.getIntegral()).build());
        }
        return new DownloadFileVO(record != null, user.getCurrentIntegral(), file.getFilePath());
    }

    /**
     * 用户删除文章
     *
     * @param articleId
     */
    public void userDeleteById(String articleId) {
        if (!Objects.equals(articleMapper.getById(articleId).getUserId(), BaseContext.getCurrentId())) {
            throw new BaseException(MessageConstant.DELETION_FAILURE);
        }
        //删除板块下所有评论
        commentMapper.deleteByArticleId(articleId);
        //删除板块下所有附件
        attachmentMapper.deleteByArticleId(articleId);
        //删除文章
        articleMapper.deleteByArticleId(articleId);
    }


    /**
     * 根据日期查询文章数
     *
     * @param localDateTime
     * @return
     */
    public Integer getArticleCount(LocalDateTime localDateTime) {
        return articleMapper.getArticleCount(localDateTime.toLocalDate(), BaseContext.getCurrentId());
    }


}
